import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, applyMiddleware} from "redux";
import thunk from 'redux-thunk'   //redux-thunk支持异步操作

/*1. 定义 reducer(用于创建容器使用)
*   第一个参数: state 容器的初始状态, 可提供默认值
*   第二个参数: action 修改state的行为
*       type 行为类型
*       payload (可选) 其他载荷数据
* */

const defaultState = 0;
function Reducer(state = defaultState, action) {
  const { type, payload } = action
  if (type === 'ADD') {
    return state + payload;
  }else if (type === 'SUB') {
    return state - payload;
  }else {
    return state;
  }
}
/*2. 通过createStore函数创建store
*    第2个参数: preloadedState 提供初始值,将会覆盖reducer中的state值
* */
const store = createStore(Reducer, applyMiddleware(thunk));

//3. 获取容器状态
console.log(store.getState());

/*4.更新store的状态
*   store.dispatch({type:行为类型, 额外参数...})
* */
// setTimeout(()=>{
//   // 发起 dispatch 就是在调用 reducer函数
//   // dispatch 接收的参数是 action
//   store.dispatch({type: 'ADD'})
// },1000);

/*5. 监测store变化*/
store.subscribe(()=>{
  console.log(store.getState())
  render()
})


function Counter(props){
  return <div>
    <p>{props.value}</p>
    <button onClick={props.add}>addition</button>
    <button onClick={props.sub}>subtraction</button>
    <button onClick={props.asyncAdd}>异步调用dispatch</button>
  </div>
}

render()

function increment(value) {
  return {
    type: 'ADD',
    payload: value
  }
}
// 同步action函数内必须是纯函数,必须返回一个对象
// 对象必须包含一个type属性: {type: ''},
function decrease(value) {
  return {
    type: 'SUB',
    payload: value
  }
}

//异步action必须由中间件redux-thunk 才能运行,
// 异步action 返回一个函数, 该函数由thunk内部进行调用
// 异步action 返回的函数可以添加逻辑
function asyncIncrement(v) {
  return function (dispatch, getState) {
    const state = getState();
    if (state % 2 === 0) {
      return
    }
    setTimeout(()=>{
      dispatch(increment(v))
    },1000)
  }
}

function render (){
  ReactDOM.render(
    <Counter
      value={store.getState()}
      add = {()=>store.dispatch(increment(5))}
      sub = {()=>store.dispatch(decrease(2))}
      asyncAdd = {()=>store.dispatch(asyncIncrement(1))}
      />,
    document.getElementById('root')
  );
}

